#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/wait.h>
#include <signal.h>
void PrintPending(sigset_t &pending)
{
    std::cout << "curr process[" << getpid() << "]pending: ";
    for (int signo = 31; signo >= 1; signo--)
    {
        if (sigismember(&pending, signo)) //pending中由该信号打印1,没有则打印0
        {
            std::cout << 1;
        }
        else
        {
            std::cout << 0;
        }
    }
    std::cout << std::endl;
}

void handler(int signo)
{
    std::cout << signo << " 号信号被递达!!!" << std::endl;

    // 打印递达完成前的pending;
    std::cout << "-------------------------------------" << std::endl;
    sigset_t pending;
    sigpending(&pending);
    PrintPending(pending);
    std::cout << "-------------------------------------" << std::endl;
}

int main()
{
    // 0. 捕捉2号信号
    signal(2, handler); // 自定义处理一个信号
    // signal(2, SIG_IGN); // 忽略一个信号
    // signal(2, SIG_DFL); // 用默认的方式处理一个信号

    // 1. 屏蔽2号信号
    sigset_t block_set, old_set; // sigset_t Linux给用户提供的一个用户级的数据类型, 禁止用户直接修改位图
    sigemptyset(&block_set);     // 初始化位图
    sigemptyset(&old_set);

    sigaddset(&block_set, 2); // 往位图中添加二号信号,此时的内核block表还没有修改
    // 设置进入进程的Block表中
    sigprocmask(SIG_BLOCK, &block_set, &old_set);

    int cnt = 10;
    while (true)
    {
        // 2.获取pending数据集(未决)
        sigset_t pending;
        sigpending(&pending);

        // 3.打印pending数据集
        PrintPending(pending);
        cnt--;

        // 解除对2号信号的屏蔽
        if (cnt == 0)
        {
            std::cout << "解除对2号信号的屏蔽!!!" << std::endl;
            sigprocmask(SIG_SETMASK, &old_set, &block_set);
            std::cout << "********************************" << std::endl;
            sigpending(&pending);
            PrintPending(pending);
        }
        sleep(1);
    }
    return 0;
}

// int main()
// {
//     pid_t id = fork();
//     if (id == 0)
//     {
//         int a = 10;
//         a /= 0;
//         exit(0);
//     }

//     int status = 0;
//     int rid = waitpid(id, &status, 0);
//     if (rid > 0)
//     {
//         printf("exit code:%d,exit sig:%d,core:%d\n", (status >> 8) & 0xff, status & 0x7f, (status >> 7) & 1);
//     }
//     return 0;
// }